﻿using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Projections;
using DotSpatial.Symbology;
using Microsoft.Office.Interop.Excel;
using Search3xls;
using Search3xls.Searching;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HydroDesktop.DataDownload.Downloading;
using HydroDesktop.DataDownload.LayerInformation.PopupControl;
using HydroDesktop.DataDownload.LayerInformation;
using HydroDesktop.DataDownload.SearchLayersProcessing;
using HydroDesktop.DataDownload;

namespace DotSpatialExcelAddIn
{
    public partial class frmMap : Form
    {
        private readonly IServiceInfoExtractor _serviceInfoExtractor;
        //private readonly Map _map;
        private readonly Popup toolTip;
        private readonly CustomToolTipControl customToolTip;
        private readonly DataDownloadPlugin _parentPlugin;

        bool dropLegendChk = true;
        addinRibbon rb;
        public addinRibbon Rb
        {
            get { return rb; }
            set { rb = value; }
        }
        int frmHeight = 0;
        //----------------------Interface Map for Ribbon---------------------------
        IMap XLSMap;
        public IMap mapInterface
        {
            get { return map1; }
            set { XLSMap = (Map)value; }
        }
        //-------------------------------------------------------------------------
        
        public frmMap()
        {
            InitializeComponent();
            //map1.Layers.Add(BruTileLayer.CreateOsmLayer());
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            if (this.Height == 88)
            {
                this.Height = frmHeight;
            }
            else
            {
                frmHeight = this.Height;
                this.Height = 88;
            }
            /*
            Microsoft.Office.Interop.Excel.Application oXL;
            Microsoft.Office.Interop.Excel.Workbook oWB;
            Microsoft.Office.Interop.Excel.Worksheet oSheet;
            oXL = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
            oXL.Visible = true;
            oWB = (Microsoft.Office.Interop.Excel.Workbook)oXL.ActiveWorkbook;
            MessageBox.Show(oWB.Worksheets.Count.ToString());
            for (int i = oWB.Worksheets.Count; i>= 1; i--)
            {
                oSheet = (Worksheet)oWB.Worksheets[i];
                oSheet.Delete(); 
            }
            oWB.Worksheets.Add();
            oSheet = (Worksheet)oWB.Worksheets[1];
            
            //oSheet = (Worksheet)oWB.Worksheets["Sheet1"];
            oSheet.Name = "Kasem";
             */
        }

        private void frmMap_Load(object sender, EventArgs e)
        {
            //textBox1.Text = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);           
            //-----------------
            this.Opacity = opacityBar.Value * 0.01;
            rb.enableTool = true;
            comboBox1.Text = "Bring map"; 
            //map1.Layers.Add(BruTileLayer.CreateBingHybridLayer());
            double x1 = map1.ViewExtents.MinX;
            double y1 = map1.ViewExtents.MinY;
            double x2 = map1.ViewExtents.MaxX;
            double y2 = map1.ViewExtents.MaxY;
            rb.editBoxX1.Text = x1.ToString();
            rb.editBoxY1.Text = y1.ToString();
            rb.editBoxX2.Text = x2.ToString();
            rb.editBoxY2.Text = y2.ToString();

            //-----------------
        }
        
        private void frmMap_FormClosed(object sender, FormClosedEventArgs e)
        {
            rb.enableTool = false;
        }

        private void spatialStatusStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
        }

#region "legend"
       
        private void legend1_MouseHover(object sender, EventArgs e)
        {
            legend1.Height = map1.Top + map1.Height;    
        }

        private void legend1_MouseLeave(object sender, EventArgs e)
        {
            if (dropLegendChk==true) legend1.Height = 20;    
        }

        private void picDropLegend_Click(object sender, EventArgs e)
        {
                legend1.Height = map1.Top + map1.Height;
                dropLegendChk = false;
                picLegendUp.Visible = true;
                picDropLegend.Visible = false;
        }

        private void picLegendUp_Click(object sender, EventArgs e)
        {
                legend1.Height = 20;
                dropLegendChk = true;
                picDropLegend.Visible = true;
        }
  
#endregion

        private void opacityBar_Scroll(object sender, EventArgs e)
        {
            this.Opacity = opacityBar.Value * 0.01;
           //this.Refresh(); 
        }

        private void cmdOpenOnlinemap_Click(object sender, EventArgs e)
        {
            string keyword = "Water depth, stream";
            //When?
            //-----------------------------------------------------
            DateTime startDate = DateTime.Today;
            DateTime nDaysAgo = DateTime.Today.AddDays(-365 * 5);
            DateTime finishDate = nDaysAgo;

            //Where?
            //------------------------------------------------------
            double x1 = -12601641.49;
            double y1 = 4948244.62;
            double x2 = -12417745.49;
            double y2 = 5121231.28;

            Extent ext = new Extent(x1, y1, x2, y2);
            ProjectionInfo myProjection = new ProjectionInfo();
            ProjectionInfo target = KnownCoordinateSystems.Projected.World.WebMercator;
            // myProjection = KnownCoordinateSystems.Geographic.World.WGS1984;

            HydroDesktopSearch x = new HydroDesktopSearch(startDate, finishDate, keyword, ext, target);
            Task<SearchResult> tResult = x.Searcher._searchTask;
            SearchResult p = tResult.Result;

            for (int i = map1.Layers.Count - 1; i >= 0; i--)
            {
                string str = map1.Layers[i].LegendText;
                string str2 = str.Substring(0, 11);
                if (str2.ToUpper() != "Brutile.Web".ToUpper())
                {
                    map1.Layers.RemoveAt(i);
                }
            }
            foreach (var item in p.ResultItems)
            {
                FeatureSet fe = item.FeatureSet as FeatureSet;
                map1.Layers.Add(fe);
                //LAT and LONG Coordinate
                //Need to convert to UTM
            }

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            for (int i = map1.Layers.Count - 1; i >= 0; i--)
            {
                string str = map1.Layers[i].LegendText;
                string str2 = str.Substring(0, 11);
                if (str2.ToUpper() == "Brutile.Web".ToUpper())
                {
                    map1.Layers.RemoveAt(i);
                }
            }

            if (comboBox1.Text == "OSM") map1.Layers.Add(BruTileLayer.CreateOsmLayer());
            if (comboBox1.Text == "Bring map") map1.Layers.Add(BruTileLayer.CreateBingHybridLayer());
            if (comboBox1.Text == "Yahoo map") map1.Layers.Add(BruTileLayer.CreateGoogleSatelliteLayer());
            for (int i = map1.Layers.Count - 1; i >= 0; i--)
            {
                string str = map1.Layers[i].LegendText;
                string str2 = str.Substring(0, 11);
                if (str2.ToUpper() == "Brutile.Web".ToUpper())
                {
                    IMapLayer iMapLayer = map1.Layers[i];
                    for (int j = i; j > 0; j--)
                    {
                        map1.Layers[j] = map1.Layers[j - 1];
                    }
                    map1.Layers[0] = iMapLayer;
                }
            }
        }

        private void frmMap_Activated(object sender, EventArgs e)
        {
            rb.enableTool = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void cmdDownload_Click(object sender, EventArgs e)
        {
            frmSelectActiveSheet formDownload = new frmSelectActiveSheet();
            formDownload.Map1 = this.map1; 
            formDownload.ShowDialog(); 
        }

        public void StartDownloading(IFeatureLayer featureLayer, IEnumerable<IFeature> featuresToDownload = null)
        {
            if (featuresToDownload == null)
            {
                featuresToDownload = featureLayer.DataSet.Features;
            }
            var dataThemeName = featureLayer.LegendText;
            var oneSeriesList = featuresToDownload.Select(f => ClassConvertor.IFeatureToOneSeriesDownloadInfo(f, featureLayer)).ToList();
            var startArgs = new StartDownloadArg(oneSeriesList, dataThemeName);
            StartDownloading(startArgs, featureLayer);
        }

        public void StartDownloading(StartDownloadArg startArgs, IFeatureLayer layer)
        {
            if (startArgs == null) throw new ArgumentNullException("startArgs");
            //if (ShowIfBusy()) return;

            startArgs.FeatureLayer = layer;
            //DownloadManager.Start(startArgs);
        }

        private void DoDownload(object sender, EventArgs args)
        {
            //KASEM PINTHONG 2014-03-27

            //if (ShowIfBusy()) return;

            var hasPointsToDownload = false;
            //foreach (var layer in App.Map.MapFrame.GetAllLayers())
            foreach (var layer in map1.MapFrame.GetAllLayers())
                {
                if (!layer.Checked || !SearchLayerModifier.IsSearchLayer(layer)) continue;

                var featureLayer = (IFeatureLayer)layer;
                if (featureLayer.Selection.Count == 0) continue;
                hasPointsToDownload = true;

               // StartDownloading(featureLayer, featureLayer.Selection.ToFeatureList());
                break;
            }

            if (!hasPointsToDownload)
            {
                MessageBox.Show("No results are selected for download. Please select sites in the map, or select series from the selected layer table.",
                                "No selected sites", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }


        private void map1_MouseMove(object sender, MouseEventArgs e)
        {
           // Extent ext = new Extent();
           // ext = map1.ViewExtents;
           // this.Text = ext.MinX.ToString() + "," + ext.MinY.ToString() + " - " + ext.MaxX.ToString() + "," + ext.MaxY.ToString();

            /*
            if (!_parentPlugin.ShowPopups)
            {
                return;
            }
            
            
            List<ILayer> myLayer = new List<ILayer>();
            IFeatureSet FeLyr = map1.Layers[1].DataSet as IFeatureSet;
            MapPointLayer mapLyr = new MapPointLayer(FeLyr);
            myLayer.Add(mapLyr); 

            //var visibleLayers = map1.GetAllLayers().OfType<IFeatureLayer>()
            //                                       .Where(layer => layer.IsVisible && SearchLayerModifier.IsSearchLayer(layer))
            //                                       .ToList();
            var visibleLayers = myLayer;
            if (visibleLayers.Count == 0)
            {
//                HideToolTip();
                return;
            }
            
/*            
            var rtol = new System.Drawing.Rectangle(e.X - 8, e.Y - 8, 0x10, 0x10);
            var tolerant = map1.PixelToProj(rtol);
            
            var pInfos = visibleLayers.Select(layer => Identify(layer, tolerant)).Where(pInfo => !pInfo.IsEmpty).ToList();

            if (pInfos.Count == 0)
            {
                HideToolTip();
                //return;
            }
            
            // If already visible same tooltip, not show again
            
             
            var control = (CustomToolTipControl)toolTip.Content;
            if (toolTip.Visible && control.IsInfoAlreadySetted(pInfos))
                return;

            HideToolTip();
            control.SetInfo(pInfos);

            
            System.Drawing.Point adjustedLocation = adjustPopupLocation(e.Location);
            toolTip.Show(map1, toolTip.Parent.PointToClient(adjustedLocation));
*/            
        }

        private System.Drawing.Point adjustPopupLocation(System.Drawing.Point start)
        {
            int tempX = start.X;
            int tempY = start.Y;

            //If popup goes over right edge of map pull it to the left.
            if (toolTip.Width + start.X > map1.Right)
            {
                tempX = tempX - ((toolTip.Width + start.X) - map1.Right);
            }
            //If popup goes below the edge of the map, make it appear above the cursor.
            if (toolTip.Height + start.Y > map1.Bottom)
            {
                tempY = tempY - toolTip.Height;
            }

            System.Drawing.Point adjustedPoint = new System.Drawing.Point(tempX, tempY);
            return adjustedPoint;
        }

        private void HideToolTip()
        {
            toolTip.Close();
        }

        private ServiceInfoGroup Identify(IFeatureLayer layer, Extent tolerant)
        {
            System.Diagnostics.Debug.Assert(layer != null);

            var group = new ServiceInfoGroup();
            foreach (var feature in layer.DataSet.Select(tolerant))
            {
                if (feature.DataRow == null)
                {
                    feature.ParentFeatureSet.FillAttributes();
                }
                var pInfo = ClassConvertor.IFeatureToServiceInfo(feature, layer);
                var serviceDescription = _serviceInfoExtractor.GetServiceDesciptionUrl(pInfo.ServiceUrl);
                if (serviceDescription != null)
                {
                    pInfo.ServiceDesciptionUrl = serviceDescription;
                }
                group.AddOverlappedServiceInfo(pInfo);
            }

            return group;
        }


        private void map1_Load(object sender, EventArgs e)
        {

        }

        private void map1_MouseUp(object sender, MouseEventArgs e)
        {
            double x1 = map1.ViewExtents.MinX;
            double y1 = map1.ViewExtents.MinY;
            double x2 = map1.ViewExtents.MaxX;
            double y2 = map1.ViewExtents.MaxY;
            rb.editBoxX1.Text = x1.ToString();
            rb.editBoxY1.Text = y1.ToString();
            rb.editBoxX2.Text = x2.ToString();
            rb.editBoxY2.Text = y2.ToString();
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
        }



    }
}
